<?php

namespace StudyBuddy\Controllers;

use \StudyBuddy\String\HTMLStringParser;
use \StudyBuddy\Responder;
use \StudyBuddy\Request;
use \StudyBuddy\Utf8String;

/**
 * Controller for processing "Edit"
 * form for editing Question or Answer
 *
 * @todo should move the parsing to
 * new class so the whole parsing thing
 * can later be used from the API and not just
 * from this controller.
 *
 */
class Editor extends Edit
{

	protected $membersOnly = true;

	protected $requireToken = false;

	protected $bRequirePost = true;

	protected $aRequired = array('rid', 'rtype');

	/**
	 * Object Utf8String represents body
	 * of question
	 *
	 * @var object of type Utf8string
	 */
	protected $oBody;


	protected function main(){
		$this->getResource()
		->checkPermission()
		->makeForm();

		if($this->oForm->validate()){
			$this->process()->updateQuestion()->returnResult();
		} else {
			$this->returnErrors();
		}

	}


	protected function returnErrors(){
		d('cp');

		if(Request::isAjax()){
			d('cp');
			$aErrors = $this->oForm->getErrors();

			Responder::sendJSON(array('formErrors' => $aErrors));
		}

		$this->makeTopTabs()
		->makeMemo()
		->setForm();
	}


	/**
	 *
	 * Process submitted form values
	 */
	protected function process(){
		$this->oRegistry->Dispatcher->post($this->oResource, 'onBeforeEdit');

		$formVals = $this->oForm->getSubmittedValues();
		d('formVals: '.print_r($formVals, 1));

		$this->oResource['b'] = $this->makeBody($formVals['qbody']);
		$this->oResource['intro'] = Utf8String::factory($formVals['qbody'])->asPlainText()->truncate(150)->valueOf();
		$this->oResource['i_words'] = $this->oBody->asPlainText()->getWordsCount();
		
		/**
		 * @important Don't attempt to edit the value of title
		 * for the answer since it technically does not have the title
		 * If we don't skip this step for Answer then title
		 * of answer will be removed
		 */
		if($this->oResource instanceof \StudyBuddy\Question){
			$oTitle = $this->makeTitle($formVals['title']);
			$title = $oTitle->valueOf();
			$this->oResource['level'] = $formVals['level'];
			$this->oResource['subject'] = $formVals['subject'];
			$this->oResource['chapter'] = $formVals['chapter'];
			$this->oResource['dif'] = $formVals['dif'];
			
			$this->oResource['title'] = $title;
			$this->oResource['url'] = $oTitle->toASCII()->makeLinkTitle()->valueOf();
			$this->oResource['a_title'] = \StudyBuddy\TitleTokenizer::factory($oTitle)->getArrayCopy();
		
			/**
			 * @todo
			 * Need to update 'title' of all answers to this question
			 * But first check to see if title has actually changed
			 */
		
		}

		$this->oResource->setEdited($this->oRegistry->Viewer, \strip_tags($formVals['reason']));
		$this->oResource->touch()->save();

		$this->oRegistry->Dispatcher->post($this->oResource, 'onEdit');

		return $this;
	}


	/**
	 *
	 * Update the contents of body
	 * with edited content
	 * If this is a question do extra steps;
	 * unhighlight (just in case that actual highlighed words
	 * have been edited), then re-apply highlightWords()
	 * just in case some of the new word that belong to
	 * tags have been added
	 *
	 * @param string $body
	 *
	 * @return string html of new body
	 *
	 */
	protected function makeBody($body){
		/**
		 * Must pass array('drop-proprietary-attributes' => false)
		 * otherwise tidy removes rel="code"
		 */
		$aEditorConfig = $this->oRegistry->Ini->getSection('EDITOR');
		$tidyConfig = ($aEditorConfig['ENABLE_CODE_EDITOR']) ? array('drop-proprietary-attributes' => false) : null;
		
		$this->oBody = Utf8String::factory($body)
		->tidy($tidyConfig)
		->safeHtml()
		->asHtml();

		$oBody = HTMLStringParser::factory($this->oBody)->parseCodeTags()->linkify()->reload()->setNofollow();

		if($this->oResource instanceof \StudyBuddy\Question){
			$oBody->unhilight()->hilightWords($this->oResource['a_tags']);
		}

		$htmlBody = $oBody->valueOf();

		d('after HTMLStringParser: '.$htmlBody);

		return $htmlBody;
	}
        
	/**
	 * Make new value of title
	 *
	 * @param string $title
	 *
	 * @return object of type Utf8String
	 */
	protected function makeTitle($title){
		$oTitle = Utf8String::factory($title)->htmlentities()->trim();
		d('$oTitle '.$oTitle);

		return $oTitle;
	}


	/**
	 * If Edited resource was an ANSWER then we must update
	 * last-modified of its QUESTION
	 *
	 * @return object $this
	 */
	protected function updateQuestion(){
		if('ANSWERS' === $this->collection){
			d('need to update QUESTION');

			try{
				$this->oRegistry->Mongo->QUESTIONS->update(array('_id' => $this->oResource['i_qid']),
				array(
					'$set' => array(
									'i_lm_ts' => time(), 
									'i_etag' => time())
				)
				);
			} catch(\MongoException $e){
				d('unable to update question '.$e->getMessage());
			}
		}

		if($this->collection == 'QUESTIONS'){
			$this->makeActionCount('question_edited_total');
		}else{
			$this->makeActionCount('answer_edited_total');
		}
		
		return $this;
	}
	
	//hoangto make action count
	function makeActionCount($countType = ''){
	
		$coll = $this->oRegistry->Mongo->ACTIONCOUNT;
	
		$count = $coll->findOne(array('i_uid' => $this->oResource['i_uid']), array('_id',$countType));
		
		if(empty($count[$countType])){
			$total = 1;
		}else{
			$total = (int)$count[$countType] + 1;
		}
			
		if(empty($count['_id'])){
			$countData = array(
				'i_uid' => $this->oResource['i_uid'],
				$countType => $total
			);
			$this->oRegistry->Mongo->ACTIONCOUNT->insert($countData);
		}else{
			$countData = array(
				'$set' => array($countType => $total)
			);
			$this->oRegistry->Mongo->ACTIONCOUNT->update(array('i_uid' => $this->oResource['i_uid']),$countData);
		}
		
		$coll->ensureIndex(array('i_uid' => 1));
		
		$this->checkGainBadges($countType, $this->oResource['i_uid']);
		
		return $this;
	}
	
	//hoangto
	protected function checkGainBadges($countType, $uid){
		
		$count = $this->oRegistry->Mongo->ACTIONCOUNT->findOne(array('i_uid' => $uid), array($countType));
		$cond = $this->oRegistry->Mongo->BADGES->find(array('cond_type' => $countType, 'cond' => array('$lte' => $count[$countType])));
		
		foreach($cond as $obj){
			$actData = array(
				'i_uid' => $uid,
				'username' => $this->oResource['username'],
				'i_bid' => $obj['id'],
				'badges' => $obj['b_name'],
				'badges_type' => $obj['type']
			);
			$isExist = $this->oRegistry->Mongo->USER_BADGES->findOne($actData);
			if(empty($isExist)){
				$this->oRegistry->Mongo->USER_BADGES->insert($actData);
				$this->makeActivities('badges', 'earned a badges', $obj['id']);
			}
			$this->oRegistry->Mongo->USER_BADGES->ensureIndex(array('i_uid' => 1));
			$this->oRegistry->Mongo->USER_BADGES->ensureIndex(array('badges' => 1));
		}
		
		return $this;
	}
	
	//hoangto make answer activity
	protected function makeActivities($act_type = 'a', $act_name = 'answered a question', $act_id) {
		$actData = array(
			'i_uid' => $this->oResource['i_uid'],
			'username' => $this->oResource['username'],
			'avt' => $this->oResource['avtr'],
			'act_type' => $act_type,
			'act_id' => $act_id,
			'act_name' => $act_name,
			'i_ts' => time(),
			'hts' => date('F j, Y g:i a T')
		);
	
		$coll = $this->oRegistry->Mongo->ACTIVITIES;
		$coll->ensureIndex(array('i_uid' => 1));
		$coll->ensureIndex(array('i_ts' => 1));
		
		$oActivity = \StudyBuddy\MongoDoc::factory($this->oRegistry, 'ACTIVITIES', $actData);
		$res = $oActivity->save($actData);
		
		return $this;
	}


	protected function returnResult(){

		Responder::redirectToPage($this->oResource->getUrl());
	}
}
